﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using MyClever.Lib;

namespace MyCleverMissionEditor
{
    public class DoubleBufferedTabControl : TabPage
    {
        public event DragEventHandler PluginAdded;
        private RelativePluginPosition relativePluginPosition;
        private Rectangle placeholderRectangle;

        public RelativePluginPosition RelativePluginPosition
        {
            get { return this.relativePluginPosition; }
        }

        public DoubleBufferedTabControl()
            : base()
        {
            this.DoubleBuffered = true;
            this.SetStyle
                (
                    ControlStyles.UserPaint |
                    ControlStyles.AllPaintingInWmPaint |
                    ControlStyles.ResizeRedraw |
                    ControlStyles.OptimizedDoubleBuffer |
                    ControlStyles.SupportsTransparentBackColor,
                    true
                );

            this.DragOver += new System.Windows.Forms.DragEventHandler(OnDragOver);
            this.DragDrop += new System.Windows.Forms.DragEventHandler(OnDragDrop);

            this.placeholderRectangle = new Rectangle();
            this.relativePluginPosition = null;
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            // do nothing - important for double buffer rendering performance
        }

        public void Refresh(MissionPluginLoopNode pluginProxyNode)
        {
            this.Controls.Clear();
            this.UpdateMissionPluginTreeView(pluginProxyNode, new Point(20, 20), 0);
        }

        private void UpdateMissionPluginTreeView(MissionPluginLoopNode pluginProxyNode, Point location, int loopDepth)
        {
            // loop through all plugins
            for (int i = 0; i < pluginProxyNode.PluginNodes.Count; i++)
            {
                if (typeof(MissionPluginLoopNode) == pluginProxyNode.PluginNodes[i].GetType())
                {
                    this.UpdateMissionPluginTreeView((MissionPluginLoopNode)pluginProxyNode.PluginNodes[i], location, 1);
                }
                else //MissionPluginProxy
                {
                    PluginSheet pluginForm = new PluginSheet((MissionPluginProxy)pluginProxyNode.PluginNodes[i]);
                    this.Controls.Add(pluginForm); // this calls the Load method of the pluginSheet, which calculates the form size

                    pluginForm.Location = location;
                    if (loopDepth > 0)
                    {
                        location.Y += pluginForm.Size.Height + 50;
                    }
                    else
                    {
                        location.X += pluginForm.Size.Width + 50;
                    }
                }
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            int localX = this.HorizontalScroll.Value;
            int localY = this.VerticalScroll.Value;

            //base.OnPaint(e);

            Bitmap bmp = new Bitmap(e.ClipRectangle.Width, e.ClipRectangle.Height);
            Graphics graphics = Graphics.FromImage(bmp);

            graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            graphics.FillRectangle(Brushes.White, new Rectangle(new Point(0, 0), this.ClientSize));
            graphics.DrawString("Test Double Buffering", new Font("Arial", 52), new SolidBrush(Color.Red), 20 - localX, 190 - localY);

            //if (false == this.DesignMode && this.lastMousePositon != new Point())
            //{
            //    graphics.DrawLine(new Pen(Brushes.Green, 3), this.lastMousePositon, this.PointToClient(Cursor.Position));
            //}

            if (false == this.DesignMode && null != this.relativePluginPosition)
            {
                ////graphics.DrawRectangle(new Pen(Brushes.Green, 3), this.rectangle);
                //graphics.DrawLine(new Pen(Brushes.Green, 3), new Point(this.rectangle.Left - localX, this.rectangle.Top - localY), new Point(this.rectangle.Left - localX, this.rectangle.Bottom - localY));
                //graphics.DrawLine(new Pen(Brushes.Green, 3), new Point(this.rectangle.Left - localX, this.rectangle.Bottom - localY), new Point(this.rectangle.Right - localX, this.rectangle.Bottom - localY));

                //Rectangle placeholderRectangle = this.CalcPlaceholderRectangle(mousePosition, out isValid, out isVertical);

                // draw the placeholder
                if (DockOrientation.None != this.relativePluginPosition.orientation)
                {
                    Point[] triangle1;
                    Point[] triangle2;

                    if (DockOrientation.Left == this.relativePluginPosition.orientation || DockOrientation.Right == this.relativePluginPosition.orientation)
                    {
                        triangle1 = new Point[3]{
                                                           new Point(placeholderRectangle.X, placeholderRectangle.Y),
                                                           new Point(placeholderRectangle.X - 8, placeholderRectangle.Y - 8),
                                                           new Point(placeholderRectangle.X + 8, placeholderRectangle.Y - 8)};

                        triangle2 = new Point[3]{
                                                            new Point(placeholderRectangle.X, placeholderRectangle.Y + placeholderRectangle.Height),
                                                            new Point(placeholderRectangle.X - 8, placeholderRectangle.Y + placeholderRectangle.Height + 8),
                                                            new Point(placeholderRectangle.X + 8, placeholderRectangle.Y + placeholderRectangle.Height + 8)};
                    }
                    else
                    {
                        triangle1 = new Point[3]{
                                                           new Point(placeholderRectangle.X + 8, placeholderRectangle.Y),
                                                           new Point(placeholderRectangle.X, placeholderRectangle.Y - 8),
                                                           new Point(placeholderRectangle.X, placeholderRectangle.Y + 8)};

                        triangle2 = new Point[3]{
                                                            new Point(placeholderRectangle.X + placeholderRectangle.Width, placeholderRectangle.Y),
                                                            new Point(placeholderRectangle.X + placeholderRectangle.Width + 8, placeholderRectangle.Y - 8),
                                                            new Point(placeholderRectangle.X + placeholderRectangle.Width + 8, placeholderRectangle.Y + 8)};
                    }

                    graphics.FillPolygon(Brushes.Black, triangle1);
                    graphics.FillPolygon(Brushes.Black, triangle2);
                    graphics.FillRectangle(Brushes.Black, placeholderRectangle);
                }
            
            }

            e.Graphics.DrawImageUnscaled(bmp, 0, 0);

            graphics.Dispose();
        }

        protected override void OnScroll(ScrollEventArgs sender)
        {
            this.Invalidate();
        }

        private void OnDragOver(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("MyClever.Lib.AvailablePlugin", false))
            {
                e.Effect = DragDropEffects.Move;

                foreach (PluginSheet pluginFormOn in this.Controls)
                {
                    if (pluginFormOn.IsMouseOver(this.PointToClient(new Point(e.X, e.Y)), true))
                    {
                        this.relativePluginPosition =  pluginFormOn.GetPlaceholderByMouse(this.PointToClient(new Point(e.X, e.Y)), out this.placeholderRectangle);
                    }
                }
                this.Refresh();
            }
        }

        private void OnDragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("MyClever.Lib.AvailablePlugin", false))
            {
                this.PluginAdded(this, e);
                
                this.relativePluginPosition = null;
                this.Refresh();
            }
        }
    }
}
